package com.rui.sideup.module.codegen.core.gen;

import com.rui.sideup.module.codegen.core.extractor.ColumnFilter;
import com.rui.sideup.module.codegen.core.model.Column;
import com.rui.sideup.module.codegen.core.model.Table;
import com.rui.sideup.module.codegen.core.utils.ConfigUtils;
import com.rui.sideup.module.codegen.core.utils.NameUtils;
import com.rui.sideup.module.codegen.core.utils.ThymeleafFacade;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public abstract class AbstractTableGenerator extends AbstractGenerator {

    protected Table table;

    private List<ColumnFilter> filters = new ArrayList<>();

    public AbstractTableGenerator() {
    }

    public AbstractTableGenerator(Table table) {
        super();
        this.table = table;
    }

    @Override
    public final String generate() {
        this.filter();
        return ThymeleafFacade.getResult(getTemplateName(), getDataModel());

    }

    @Override
    public final void generate(String file) throws IOException {
        File f = new File(file);
        if (!f.exists()) {
            if (!f.getParentFile().exists()) {
                f.getParentFile().mkdirs();
            }
            f.createNewFile();
        }
        this.filter();
        ThymeleafFacade.getResult(getTemplateName(), getDataModel(), file);
    }

    @Override
    public void filter() {
        List<Column> cols = table.getColumns();
        for (ColumnFilter f : filters) {
            for (int i = 0; i < cols.size(); i++) {
                Column c = cols.get(i);
                if (f.filter(c)) {
                    cols.remove(i);
                    i--;
                }
            }
        }
    }

    @Override
    public void addFilter(ColumnFilter f) {
        filters.add(f);
    }

    @Override
    public void removeFilter(ColumnFilter f) {
        filters.remove(f);
    }

    protected Map<String, Object> getDataModel() {
        Map<String, Object> data = new HashMap<>();
        data.putAll(getCfg());
        data.put("table", table);
        data.put("bean", NameUtils.getBeanName(table.getName()));
        return data;
    }

    protected String getTemplateName() {
        String clazzName = this.getClass().getSimpleName();
        return clazzName + ".txt";
    }

    protected final String getSourceFolder() {
        return ConfigUtils.getSourceFolder();
    }

    protected String package2path(String packageValue) {
        return packageValue.replace('.', File.separatorChar);
    }

    protected final boolean enableSubPackages() {
        return ConfigUtils.getEnableSubPackages();
    }

    @Override
    public String getFilePath() {
        if (enableSubPackages()) {
            return getSourceFolder() + File.separator + table.getCamelClazzName() + File.separator + package2path(getPackage(getType())) + File.separator + getFileName();
        }
        return getSourceFolder() + File.separator + table.getCamelClazzName() + File.separator + getFileName();
    }

    public Table getTable() {
        return table;
    }

    @Override
    public void setTable(Table table) {
        this.table = table;
    }

}
